package vip.xumy.admin.bmap.util;

import vip.xumy.admin.bmap.pojo.Point;

/**
 * @author:mengyxu
 * @date:2020年4月28日
 */

public class BMapTool {
	private static final double[][] BV = new double[][] {
			new double[] { -0.0015702102444, 111320.7020616939, 1704480524535203L, -10338987376042340L,
					26112667856603880L, -35149669176653700L, 26595700718403920L, -10725012454188240L, 1800819912950474L,
					82.5 },
			new double[] { 8.277824516172526E-4, 111320.7020463578, 6.477955746671607E8, -4.082003173641316E9,
					1.077490566351142E10, -1.517187553151559E10, 1.205306533862167E10, -5.124939663577472E9,
					9.133119359512032E8, 67.5 },
			new double[] { 0.00337398766765, 111320.7020202162, 4481351.045890365, -2.339375119931662E7,
					7.968221547186455E7, -1.159649932797253E8, 9.723671115602145E7, -4.366194633752821E7,
					8477230.501135234, 52.5 },
			new double[] { 0.00220636496208, 111320.7020209128, 51751.86112841131, 3796837.749470245, 992013.7397791013,
					-1221952.21711287, 1340652.697009075, -620943.6990984312, 144416.9293806241, 37.5 },
			new double[] { -3.441963504368392E-4, 111320.7020576856, 278.2353980772752, 2485758.690035394,
					6070.750963243378, 54821.18345352118, 9540.606633304236, -2710.55326746645, 1405.483844121726,
					22.5 },
			new double[] { -3.218135878613132E-4, 111320.7020701615, 0.00369383431289, 823725.6402795718,
					0.46104986909093, 2351.343141331292, 1.58060784298199, 8.77738589078284, 0.37238884252424, 7.45 } };

	public static void callXY(Point p) {
		double lan = fix(p.getLan(), -180, 180);
		double lat = fix(p.getLat(), -89.999999, 89.999999);
		int idx = 5 - (int) Math.abs(lat / 15);
		double[] b = BV[idx];
		Double c = b[0] + b[1] * Math.abs(lan);
		double d = Math.abs(lat) / b[9];
		double e = b[2] + b[3] * d + b[4] * d * d + b[5] * d * d * d + b[6] * d * d * d * d + b[7] * d * d * d * d * d
				+ b[8] * d * d * d * d * d * d;
		c *= (lan < 0 ? -1 : 1);
		e *= (lan < 0 ? -1 : 1);
		double x = Math.floor(c * Math.pow(2, p.getZ() - 18));
		double y = Math.floor(e * Math.pow(2, p.getZ() - 18));
		p.setX((int) Math.floor(x / 256));
		p.setY((int) Math.floor(y / 256));
	}

	private static double fix(double a, double b, double c) {
		return Math.min(Math.max(a, b), c);
	}

}
